import * as React from 'react'
import { Input, Button, Table, Tag, Modal, message, Form , Tooltip, Radio, Checkbox } from 'antd'
import { ExclamationCircleOutlined, InfoCircleTwoTone } from '@ant-design/icons';
import { Authority, Role, Level, User, Config } from '../../serve/interface';
import { ColumnsType } from 'antd/lib/table';

declare var __all_config__: Partial<Config>;
const LEVELS = __all_config__.auth_level
const { confirm } = Modal;
const FormItem = Form.Item

export interface RoleListProps {
    isShow?: boolean
    authorities?: Authority[]
    roles?: Role[]
    users?: User[]
    updateRoleAuthority?: (roleId: string | number, authorityId: string | number, level: number) => Promise<void>
    addRole?: (name: string) => Promise<void>
    delRole?: (roleId: string | number) => Promise<void>
}
export interface RoleListState {
    role_name: string,
    addRoleModalShow: boolean
}

interface LevelShowProps {
    level: number
    onChange: (value: number) => void
    role: Role
}
const LevelShow = ({ level = 0, onChange = (value: number) => { }, role }: LevelShowProps) => {
    if (LEVELS && LEVELS.length) {
        return <Radio.Group
            size="small"
            onChange={e => onChange(e.target.value)}
            buttonStyle="solid"
            defaultValue={role.isAdmin ? LEVELS.length - 1 : level}
            disabled={role.isAdmin}>
            {LEVELS.map((title, i) => <Radio.Button value={i + 1} key={i + 1}>{title}</Radio.Button>)}
        </Radio.Group>
    } else {
        return <Checkbox disabled={role.isAdmin} checked={role.isAdmin || level > 0} onChange={e => onChange(e.target.checked ? 1 : 0)}/>
    }
}

export default class RoleList extends React.Component<RoleListProps, RoleListState> {
    constructor(props: RoleListProps) {
        super(props)
        this.state = {
            role_name: '',
            addRoleModalShow: false
        }
    }

    top: HTMLDivElement
    refTop = (top: HTMLDivElement) => {
        this.top = top
    }
    left: HTMLDivElement
    refLeft = (left: HTMLDivElement) => {
        this.left = left
    }
    onScroll = (e: Event) => {
        this.top.scrollLeft = e.target['scrollLeft'];
        this.left.scrollTop = e.target['scrollTop'];
    }
    render() {
        const { authorities = [], roles = [], users = [], updateRoleAuthority, isShow } = this.props
        const { role_name } = this.state;
        const inUse = (role: Role) => !!users.find(u => u.roleId === role.id)
        let _roles = roles.map(i => {
            return {
                ...i,
                key: i.id
            }
        })
        let authColumns: ColumnsType<Role> = authorities.map(auth => {
            return {
                title: auth.name,
                dataIndex: auth.id,
                key: auth.id,
                width: LEVELS ? LEVELS.length * 50 : 40,
                render: (text, role) => {
                    return <div>
                        <LevelShow level={role.authorities && role.authorities[auth.id]}
                            onChange={level => updateRoleAuthority(role.id, auth.id, level)}
                            role={role}
                        />
                    </div>
                }
            }
        })

        let columns: ColumnsType<Role> = [
            {
                title: '角色/权限',
                dataIndex: 'name',
                key: 'name',
                width: 150,
                fixed: 'left',
                render: (text, data) => <div>
                    <Tag color='green'>{text}</Tag>
                    {(inUse(data) || data.isSys) ? <Tooltip title={data.isSys ? '内置角色不可删除' : '用户关联,不可删除'}><InfoCircleTwoTone /></Tooltip>
                        : <a title="删除角色" onClick={(e) => this.delRole(data.id)}>删除</a>}
                </div>
            },

        ]
        columns = columns.concat(authColumns)
        const formItemLayout = {
            labelCol: { span: 4 },
            wrapperCol: { span: 20 },
        }
        return <div>
            <div style={{ marginBottom: 20 }}>
                <Button type="primary" onClick={this.addRoleModalOnShow}>
                    添加角色
                </Button>
            </div>
            <Table key="id" dataSource={_roles} columns={columns} bordered scroll={{ x: `${ 12.5 * columns.length > 100 ? 12.5 * columns.length : 100 }%` }} size="small" />
            <Modal
                title="添加角色"
                visible={this.state.addRoleModalShow}
                onCancel={this.addRoleModalHide}
                onOk={this.addRole}
                maskClosable={false}
                cancelText="取消"
                okText="确定"
            >
                <Form>
                    <FormItem {...formItemLayout} label="角色名称" required>
                        <Input type="text" value={role_name} onChange={(e) => this.changeValue(e)} />
                    </FormItem>
                </Form>
            </Modal>

        </div>
    }

    addRole = () => {
        let name = this.state.role_name, that = this;
        const roleNameArr = this.props.roles.map((item) => item.name)
        if (name.length === 0) {
            message.warning('请填写角色名称')
            return
        }
        if (roleNameArr.find((i) => i=== name)) {
            message.warning(`已存在"${name}"的角色`)
            return
        }
        this.props.addRole(name).then(res => {
            message.success('添加成功')
            that.setState({
                role_name: '',
                addRoleModalShow: false
            })
        });
    }

    delRole = (roleId: number | string) => {
        confirm({
            icon: <ExclamationCircleOutlined />,
            content: "确定要删除该角色吗?",
            onOk: () => {
                this.props.delRole(roleId);
            },
            cancelText: "取消",
            okText: "确定"
        });
    }

    changeValue = (e) => {
        this.setState({
            role_name: e.target.value.replace(/(^\s*)|(\s*$)/g, "")
        })
    }

    addRoleModalOnShow = () => {
        this.setState({
            addRoleModalShow: true
        })
    }

    addRoleModalHide = () => {
        this.setState({
            addRoleModalShow: false
        })
    }
}